import 'whatwg-fetch';

import {message} from 'antd'
import StorageUtils from 'utils/StorageUtils'

const catalogServiceUrl = 'http://localhost:8080/api/catalog-service';
const cartServiceUrl = 'http://localhost:8080/api/cart-service';
const userServiceUrl = 'http://localhost:8080/api/user-service'
const orderServiceUrl = 'http://localhost:8080/api/order-service';
const paymentServiceUrl = 'http://localhost:8080/api/payment-service';
const searchServiceUrl = 'http://localhost:8080/api/search-service';
const reviewServiceUrl = 'http://localhost:8080/api/review-service'
const systemServiceUrl = 'http://localhost:8080/api/system-service'

// const catalogServiceUrl = 'http://localhost:8801';
// const cartServiceUrl = 'http://localhost:8804';
// const userServiceUrl = 'http://localhost:8803'
// const orderServiceUrl = 'http://localhost:8802';
// const paymentServiceUrl = 'http://localhost:8806';
// const searchServiceUrl = 'http://localhost:8807';
// const reviewServiceUrl = 'http://localhost:8805'
// const systemServiceUrl = 'http://localhost:8809'

const HttpUtils = {

    productServiceUrl: catalogServiceUrl,
    specServiceUrl : catalogServiceUrl,
    productGroupServiceUrl: catalogServiceUrl,
    floorServiceUrl: catalogServiceUrl,
    categoryServiceUrl: catalogServiceUrl,
    attributeServiceUrl: catalogServiceUrl,
    cartServiceUrl: cartServiceUrl,
    userServiceUrl: userServiceUrl,
    orderServiceUrl: orderServiceUrl,
    paymentServiceUrl: paymentServiceUrl,
    searchServiceUrl: searchServiceUrl,
    commentServiceUrl: reviewServiceUrl,
    systemServiceUrl : systemServiceUrl,

    get(url, options, callback) {
        let parameterizedUrl = this.buildUrl(url, options.params);
        let request = Object.assign({
            method: 'GET',
            headers: {
            },
            credentials: 'include'
        } , options)
        let token = StorageUtils.getToken()
        if(token){
            request.headers.Authorization = 'Bearer ' + token
        }
        fetch(parameterizedUrl, request)
            .then((resp) => {
                if(resp.status >= 200 && resp.status < 300){
                    return resp.json()
                }
                let error = new Error(resp.statusText)
                error.response = resp.json()
                error.customError = true
                throw error
            })
            .then((resp) => {
                callback.success(resp);
            })
            .catch((error) => {
                if(!error.customError){
                    throw error
                }
                let promise = error.response
                promise.then(function(value){
                    if(callback.error){
                        callback.error(value)
                    } else {
                        message.error(value.error_message)
                    }
                })
            })
    },

    delete(url, callback) {
        let request = {
            method: 'DELETE',
            headers: {
            },
            credentials: 'include'
        }
        let token = StorageUtils.getToken()
        if(token){
            request.headers.Authorization = 'Bearer ' + token
        }
        fetch(url, request)
            .then((resp) => {
                if(resp.status >= 200 && resp.status < 300){
                    return resp.json()
                }
                let error = new Error(resp.statusText)
                error.response = resp.json()
                error.customError = true
                throw error
            })
            .then((resp) => {
                callback.success(resp);
            })
            .catch((error) => {
                if(!error.customError){
                    throw error
                }
                let promise = error.response
                promise.then(function(value){
                    if(callback.error){
                        callback.error(value)
                    } else {
                        message.error(value.error_message)
                    }
                })
            })
    },

    buildUrl(url, params) {
        if (typeof(url) === 'undefined' || url === null || url ==='') {
            return '';
        }
        if (typeof(params) ==='undefined' || params === null || typeof(params) !== 'object') {
            return url;
        }
        url += (url.indexOf("?") !== -1) ? "" : "?";
        for (var k in params) {
            url += ((url.indexOf("=") !== -1) ? "&" : "") + k + "=" + encodeURI(params[k]);
        }
        return url;
    },

    getQueryString(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return decodeURI(r[2]);
        return null;
    },

    changeUrlParam(url, arg, val){
        var pattern = arg+'=([^&]*)';
        var replaceText = arg+'='+val;
        return url.match(pattern) ? url.replace(eval('/('+ arg+'=)([^&]*)/gi'), replaceText) : (url.match('[\?]') ? url+'&'+replaceText : url+'?'+replaceText);
    },

    /**
     * credentials: 'include'   在执行跨域传递cookie时需要这个选项
     * @param url
     * @param data
     * @param callback
     */
    post(url, data, callback , options) {
        let request = Object.assign({
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: data,
            credentials: 'include'
        } , options)
        let token = StorageUtils.getToken()
        if(token){
            request.headers.Authorization = 'Bearer ' + token
        }
        fetch(url, request)
            .then((resp) => {
                if(resp.status >= 200 && resp.status < 300){
                    return resp.json()
                }
                let error = new Error(resp.statusText)
                error.response = resp.json()
                error.customError = true
                throw error
            })
            .then((resp) => {
                callback.success(resp);
            })
            .catch((error) => {
                if(!error.customError){
                    throw error
                }
                let promise = error.response
                promise.then(function(value){
                    if(callback.error){
                        callback.error(value)
                    } else {
                        message.error(value.error_message)
                    }
                })
            })
    },

    /* user service */
    login(user, callback) {
        this.post(this.systemServiceUrl + '/login', JSON.stringify(user), callback);
    },

    /* catalog service */
    createProduct(product , callback){
        this.post(this.productServiceUrl + '/product' , JSON.stringify(product), callback)
    },

    listCategories(callback){
        this.get(this.categoryServiceUrl + '/categories' , {} , callback)
    },

    createCategory(category , callback){
        this.post(this.categoryServiceUrl + '/category' , JSON.stringify(category), callback)
    },

    createAttribute(attribute , callback){
        this.post(this.attributeServiceUrl + '/attributeOption' , JSON.stringify(attribute), callback)
    },

    getAttribute(attrId , callback){
        this.get(this.attributeServiceUrl + '/attributeOptions/' + attrId , {} , callback)
    },

    updateAttribute(attributeOption , id , callback){
        this.post(this.attributeServiceUrl + '/attributeOption/' + id , JSON.stringify(attributeOption), callback)
    },

    listAttributes(params , callback){
        this.get(this.attributeServiceUrl + '/attributeOptions' , {params} , callback)
    },

    deleteAttribute(id , callback){
        this.delete(this.attributeServiceUrl + '/attributeOption/' + id , callback)
    },

    createSpec(spec , callback) {
        this.post(this.specServiceUrl + '/spec' , JSON.stringify(spec), callback)
    },

    updateSpec(spec , id , callback){
        this.post(this.specServiceUrl + '/spec/' + id , JSON.stringify(spec), callback)
    },

    deleteSpec(id , callback){
        this.delete(this.specServiceUrl + '/spec/' + id , callback)
    },

    listSpecs(params , callback){
        this.get(this.specServiceUrl + '/specs' , {params} , callback)
    },

    getSpec(specId , callback){
        this.get(this.specServiceUrl + '/specs/' + specId , {} , callback)
    }

}

export default HttpUtils;